﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using DotNetImage.Metadata.Types;
using System.Diagnostics;

namespace DotNetImage.Metadata
{
    public class DotNetMetadata : MetaTag
    {
        /// <summary>
        /// Contains all metatags in current image
        /// </summary>
        internal Dictionary<string, MetaTag> Nodes = new Dictionary<string, MetaTag>();

        /// <summary>
        /// Default private constructor
        /// </summary>
        private DotNetMetadata() : base(string.Empty) { }

        public void AddMetaTag(MetaTag tag)
        {
        }

        /// <summary>
        /// The static method to read and extract metadata from the file
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static DotNetMetadata Extract(string fileName)
        {
            DotNetMetadata result = new DotNetMetadata();

            try
            {
                Debug.WriteLine(Environment.NewLine + Environment.NewLine + fileName);

                Uri imageUri = new Uri(fileName);
                var decoder = BitmapDecoder.Create(imageUri, BitmapCreateOptions.None, BitmapCacheOption.Default);

                // First save the top-level metadata
                CaptureMetadata(decoder.Metadata, string.Empty, -1, result);

                // Now collect metadata for all frames
                for (int i= 0; i < decoder.Frames.Count; i++)
                {
                    Debug.WriteLine("****************** FRAME " + i + " ********************");
                    CaptureMetadata(decoder.Frames[i].Metadata, string.Empty, i, result);
                }
            }
            finally
            {
                // Force Garbage Collection 
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
            return result;
        }



        static private void CaptureMetadata(ImageMetadata imageMetadata, string query, int frameIndex, MetaTag parentTag)
        {
            BitmapMetadata bitmapMetadata = imageMetadata as BitmapMetadata;
            if (bitmapMetadata != null)
            {
                foreach (string relativeQuery in bitmapMetadata)
                {
                    string fullQuery = query + relativeQuery;
                    object metadataQueryReader = bitmapMetadata.GetQuery(relativeQuery);

                    MetaTag tag = new MetaTag(fullQuery);
                    tag.Value = metadataQueryReader;
                    parentTag.Children.Add(tag);

                    Debug.WriteLine(tag.ToString());

                    BitmapMetadata innerBitmapMetadata = metadataQueryReader as BitmapMetadata;
                    if (innerBitmapMetadata != null)
                    {
                        CaptureMetadata(innerBitmapMetadata, fullQuery, frameIndex, tag);
                    }
                }
            }
        }

    }
}
